﻿using System;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Media.Imaging;
using System.Windows.Threading;
using GurLoader;
using GurLoader.Screenshot;
using Moq;
using NUnit.Framework;

namespace GurLoaderWPF.Test.Screenshot
{
    [TestFixture]
    public class ImagingTests
    {
        [Test]
        public void NonDispatchCreateBitmapSourceFromBitmapTest()
        {
            MemoryStream ms = new MemoryStream(ResourceLoader.GetResourceBytes("Resources/bay.jpeg"));
            Image img = Image.FromStream(ms);

            Mock<IDispatcher> mockDispatcher = new Mock<IDispatcher>();

            Assert.IsNotNull(img);

            BitmapSource result = Imaging.CreateBitmapSourceFromBitmap(img, mockDispatcher.Object, false);

            Assert.IsNotNull(result);
        }

        private BitmapSource GetResourceAsBitmapSource(string resource)
        {
            MemoryStream ms = new MemoryStream(ResourceLoader.GetResourceBytes(resource));
            ms.Seek(0, SeekOrigin.Begin);

            BitmapDecoder bitmapDecoder = BitmapDecoder.Create(
                ms,
                BitmapCreateOptions.PreservePixelFormat,
                BitmapCacheOption.OnLoad);

            // This will disconnect the stream from the image completely...
            WriteableBitmap writable = new WriteableBitmap(bitmapDecoder.Frames.Single());
            writable.Freeze();

            return writable;
        }

        [Test]
        public void DispatchCreateBitmapSourceFromBitmapTest()
        {
            MemoryStream ms = new MemoryStream(ResourceLoader.GetResourceBytes("Resources/bay.jpeg"));
            Image img = Image.FromStream(ms);

            BitmapSource bmpSource = GetResourceAsBitmapSource("Resources/bay.jpeg");

            Mock<IDispatcher> mockDispatcher = new Mock<IDispatcher>();
            mockDispatcher.Setup(x=>x.Invoke(It.IsAny<Delegate>(), It.IsAny<DispatcherPriority>(), It.IsAny<Stream>())).Returns( bmpSource ).Verifiable();

            Assert.IsNotNull(img);

            BitmapSource result = Imaging.CreateBitmapSourceFromBitmap(img, mockDispatcher.Object, true);

            Assert.IsNotNull(result);
            mockDispatcher.VerifyAll();
        }

        [Test]
        public void ThrowsExceptionOnInvokeTest()
        {
            MemoryStream ms = new MemoryStream(ResourceLoader.GetResourceBytes("Resources/bay.jpeg"));
            Image img = Image.FromStream(ms);

            Mock<IDispatcher> mockDispatcher = new Mock<IDispatcher>();

            mockDispatcher.Setup(x => x.Invoke(It.IsAny<Delegate>(), It.IsAny<DispatcherPriority>(), It.IsAny<Stream>())).Throws(new Exception() ).Verifiable();

            BitmapSource result = Imaging.CreateBitmapSourceFromBitmap(img, mockDispatcher.Object, true);
            Assert.IsNull(result);
            mockDispatcher.VerifyAll();
        }

        [Test]
        [ExpectedException(typeof(ArgumentNullException))]
        public void NullSourceTest()
        {
            Image img = null;
            Mock<IDispatcher> mockDispatcher = new Mock<IDispatcher>();

            BitmapSource result = Imaging.CreateBitmapSourceFromBitmap(img, mockDispatcher.Object, true);
        }

        [Test]
        [ExpectedException(typeof(ArgumentNullException))]
        public void NullDispatcherTest()
        {
            MemoryStream ms = new MemoryStream(ResourceLoader.GetResourceBytes("Resources/bay.jpeg"));
            Image img = Image.FromStream(ms);

            IDispatcher dispatcher = null;

            BitmapSource result = Imaging.CreateBitmapSourceFromBitmap(img, dispatcher, true);
        }
    }
}
